﻿#include "pipelinebase.h"

#include "../pathbuild/pathbuild.h"
#include "../SystemConfiguration/systemconfiguration.h"
#include "pipeline_log.h"

PipelineBase::PipelineBase()
{}

PipelineBase::~PipelineBase()
{}

/****************************************************************************
 * 功能: 业务线初始化接口
 * 传参: id: 业务线编号
 ****************************************************************************/
bool PipelineBase::PipelineInit(const QString& id)
{
	if (id.isEmpty()) {
		SetPipelineErrorState("业务线编号为空，无法初始化");
		return false;
	}
	auto cfg = syscfg->GetPipelineCfgById(id);
	m_info.id = id;
	if (cfg.id != id) {
		SetPipelineErrorState("获取业务线配置出错，初始化失败");
		return false;
	}
	m_info.type = (PipelineType)cfg.type;
	m_info.rob = cfg.rob;
	m_info.grab = cfg.strat;
	m_info.putdown = cfg.end;
	if (!Init()) {	// 特性初始化
		log_error("init failed");
		return false;
	}


	/*路径生成对象初始化*/
	m_pathBuild = new PathBuild();
	for (auto& iter : cfg.paths) {
		if (!m_pathBuild->InitAll(iter)) {
			log_error("路径{}初始化失败", iter.name);
			return false;
		}
	}

	DataInit();
	m_state = PipelineTaskState::pipeline_task_idle;
	SetTraceMassage("初始化成功");
	return true;
}

/****************************************************************************
 * 功能: 任务状态获取/设置接口
 ****************************************************************************/
PipelineTaskState PipelineBase::GetPipelineTaskState()
{
	if (m_pipeError) {
		return PipelineTaskState::pipeline_error;
	}

	return m_state;
}
bool PipelineBase::SetPipelineTaskState(PipelineTaskState state)
{
	switch (state) {
	case PipelineTaskState::pipeline_error:
		if (!m_pipeError) {
			m_pipeError = true;
			m_errmsg += "调度设置异常";
		}
		break;
	case PipelineTaskState::pipeline_task_idle:
		if (m_task.isBusy) {
			log_error("{} is busy, but Set idle Now", m_info.id);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_receive:
		if (!m_task.isBusy) {
			log_error("{} not reciver valied task", m_info.id);
			return false;
		}
		if (m_state != PipelineTaskState::pipeline_task_idle) {
			log_error("{} state is {}, not ca be set to task recieve", m_info.id, (int)m_state);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_inited:
		if (m_state != PipelineTaskState::pipeline_task_receive) {
			log_error("{} state is {}, not ca be set to task inited", m_info.id, (int)m_state);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_start:
		if (m_state != PipelineTaskState::pipeline_task_inited &&
			m_state != PipelineTaskState::pipeline_task_stepStart) {
			log_error("{} state is {}, not ca be set to task start", m_info.id, (int)m_state);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_stepPrepare:
		if (m_state != PipelineTaskState::pipeline_task_start) {
			log_error("{} state is {}, not ca be set to task step prepare", m_info.id, (int)m_state);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_stepStart:
		if (m_state != PipelineTaskState::pipeline_task_stepPrepare) {
			log_error("{} state is {}, not ca be set to task step grabPos", m_info.id, (int)m_state);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_wait_finish:
		if (m_state != PipelineTaskState::pipeline_task_start) {
			log_error("{} state is {}, not ca be set to task wait finish", m_info.id, (int)m_state);
			return false;
		}
		break;
	case PipelineTaskState::pipeline_task_finish:
		if (m_state != PipelineTaskState::pipeline_task_wait_finish) {
			log_error("{} state is {}, not ca be set to task finish", m_info.id, (int)m_state);
			return false;
		}
		break;
	default:
		log_error("{} reciver error state ={}", m_info.id, (int)state);
		return false;
		break;
	}

	m_state = state;
	return true;
}

/*业务线名称获取*/
QString PipelineBase::GetPipelineId()
{
	return m_info.id;
}

PipelineInfo PipelineBase::GetPipelinenfo()
{
	return m_info;
}

/*业务线错误信息获取*/
QString PipelineBase::GetErrorMsg()
{
	if (!m_pipeError) {
		m_errmsg.clear();
	}

	return m_errmsg;
}

void PipelineBase::ClearErrorState()
{
	m_pipeError = false;
	m_errmsg.clear();
	m_writer.WriteTraceJournal(QString("业务线%1手动清错").arg(m_info.id));
}

void PipelineBase::SetPipelineErrorState(const QString& err)
{
	m_pipeError = true;
	m_errmsg = m_info.id + err;
	log_error("{}", m_errmsg);
	m_writer.WriteErrorJournal(m_errmsg);
}

void PipelineBase::SetTraceMassage(const QString& str)
{
	log_trace("{}", str);
	m_writer.WriteTraceJournal(m_info.id + ":" + str);
}

void PipelineBase::SetErrorMassage(const QString& str)
{
	log_error("{}", str);
	m_writer.WriteErrorJournal(m_info.id + ":" + str);
}

void PipelineBase::DataInit()
{
	m_task.clear();
	m_task.isBusy = false;
	m_sku.clear();
	m_exec.clear();

	m_prepareStep.clear();
	m_execStep.clear();
	m_waitFinishStep.clear();

	m_errmsg.clear();
}


PipelineTaskInfo PipelineBase::GetPipelineTaskInfo()
{
	if (!m_task.isBusy) {
		return {};
	}
	PipelineTaskInfo task = {};
	task.finishNum = m_exec.finishNum;
	task.taskId = m_task.taskId;
	task.taskNum = m_task.taskNum;
	task.skuNo = m_sku.skuNo;
	task.skuSize = m_sku.size;
	task.skuWight = m_sku.weight;
	return task;
}

/*任务信息处理接口*/
bool PipelineBase::DeleteTaskInfo()
{
	SetTraceMassage(QString("业务线%1手动删除任务").arg(m_info.id));
	DataInit();
	m_state = PipelineTaskState::pipeline_task_idle;
	log_error("{} chang to idle for manual delete task", m_info.id);
	return true;
}
bool PipelineBase::ChangTaskFinishNum(int num)
{
	SetTraceMassage(QString("业务线%1手动修改任务完成数量").arg(m_info.id));
	log_error("{} manual change finish num, form {} to {}", m_info.id, m_exec.finishNum, num);
	m_exec.finishNum = num;
	return true;
}
bool PipelineBase::TaskContinue()
{
	SetTraceMassage(QString("业务线%1手动继续执行").arg(m_info.id));
	log_trace("manual change pipe {} to pipeline_task_receive", m_info.id);

	m_prepareStep.clear();
	m_waitFinishStep.clear();
	m_execStep.clear();
	m_state = PipelineTaskState::pipeline_task_receive;
	return true;
}
bool PipelineBase::ManualTaskFinish()
{
	SetTraceMassage(QString("业务线%1手动报任务完成").arg(m_info.id));

	if (TaskFinish()) {
		log_trace("manual task finish successed");
		m_state = PipelineTaskState::pipeline_task_idle;
		return true;
	}
	log_trace("manual task finish failed");
	return false;
}


/****************************************************************************
 * 功能: 判断节拍启动条件是否具备
 * 返回值:true：节拍可以启动
 ****************************************************************************/
bool PipelineBase::IfStepStarted()
{
	if (m_execStep.valied) {
		return false;
	}
	m_exec.execNum += m_prepareStep.excuteNum;
	m_execStep = m_prepareStep;
	SetTraceMassage(QString("节拍%1开始执行").arg(m_execStep.id));
	m_prepareStep.clear();
	return true;
}

/****************************************************************************
 * 功能: 判断节拍路径是否全部完成，由节拍调用线程调用
 * 返回值:true：节拍路径全部完成
 ****************************************************************************/
bool PipelineBase::IfStepPathEmpty()
{
	return m_execStep.sendPaths.empty();
}

/****************************************************************************
 * 功能: 判断节拍路径下发完成处理函数
 * 返回值:true：节拍路径全部完成
 ****************************************************************************/
bool PipelineBase::StepExecuteFinish()
{
	if (m_waitFinishStep.valied) {
		SetPipelineErrorState("当前节拍路径已经下发完成，上一个节拍未等待完成");
		return false;
	}

	m_waitFinishStep = m_execStep;
	m_execStep.clear();
	SetTraceMassage(QString("节拍%1路径下发完成").arg(m_waitFinishStep.id));
	return true;
}

bool PipelineBase::AddPathListToPrepareStepInfo(const QString& paths)
{
	m_prepareStep.sendPaths.clear();
	m_prepareStep.waitPaths.clear();
	m_prepareStep.sendPaths = paths.split(',');
	m_prepareStep.waitPaths = paths.split(',');
	return true;
}

/****************************************************************************
 * 功能:	获取当前节拍下一条可执行路径， 由节拍调用线程调用
 * 返回值: true:获取成功
 ****************************************************************************/
bool PipelineBase::GetNextExecPath(QString& path)
{
	if (!m_execStep.valied) {
		SetPipelineErrorState("执行节拍数据无效");
		return false;
	}
	if (m_execStep.sendPaths.size() <= 0) {
		SetPipelineErrorState("执行节拍路径为空，bug");
		return false;
	}

	QString pathid = m_execStep.sendPaths.takeFirst();
	int ret = m_pathBuild->GetNextPath(pathid, path, m_execStep.grabPos, m_execStep.putPos);
	if (ret > 0) {
		SetTraceMassage(QString("节拍%2的路径%1生成成功").arg(pathid).arg(m_execStep.id));
		return true;
	} else {
		SetPipelineErrorState(QString("获取路径%1失败:%2").arg(pathid).arg(path));
		return false;
	}
}

/****************************************************************************
 * 功能: 判断任务是否完成，任务完成等待状态被调用
 * 返回值: true: 表示任务完成
 ****************************************************************************/
bool PipelineBase::IfTaskFinished()
{
	if (m_exec.finishNum == m_task.taskNum) {
		SetTraceMassage(QString("任务%1已完成").arg(m_task.taskNum));
		return true;
	}

	return false;
}

/****************************************************************************
 * 功能: 路径启动前处理接口、路径结束后处理接口, 路径动作执行接口
 * 传参: path: 路径名称， type: 路径动作类型 pram:路径动作参数
 * 返回值: true：表示成功
 ****************************************************************************/
bool PipelineBase::PathFinished(const QString& path)
{
	if (m_waitFinishStep.valied) {
		auto& paths = m_waitFinishStep.waitPaths;
		QString id = paths.takeFirst();
		if (id == path) {
			PathEnd(path);
			SetTraceMassage(QString("节拍%1的路径%2执行完成").arg(m_waitFinishStep.id).arg(path));
		} else {
			SetPipelineErrorState(QString("错误的完成路径[%1], 正常值[%2]").arg(path).arg(id));
			paths.push_front(id);
		}
		if (paths.isEmpty()) {
			m_exec.finishNum += m_waitFinishStep.excuteNum;
			m_exec.execNum -= m_waitFinishStep.excuteNum;
			SetTraceMassage(QString("节拍%1完成，已完成任务数量%2，剩余数量%3")
				.arg(m_waitFinishStep.id).arg(m_exec.finishNum).
				arg(m_task.taskNum - m_exec.finishNum)
			);
			m_waitFinishStep.clear();
		}
	} else {
		auto& paths = m_execStep.waitPaths;
		QString id = paths.takeFirst();
		if (id == path) {
			PathEnd(path);
			SetTraceMassage(QString("节拍%1的路径%2执行完成").arg(m_execStep.id).arg(path));
		} else {
			SetPipelineErrorState(QString("错误的完成路径[%1], 正常值[%2]").arg(path).arg(id));
			paths.push_front(id);
		}
		if (paths.isEmpty()) {
			log_error("error statuation");
			m_exec.finishNum += m_execStep.excuteNum;
			m_exec.execNum -= m_execStep.excuteNum;
			SetTraceMassage(QString("节拍%1完成，已完成任务数量%2，剩余数量%3")
				.arg(m_execStep.id).arg(m_exec.finishNum).arg(m_task.taskNum - m_exec.finishNum));
		}
	}
	return true;
}
bool PipelineBase::PathAction(int type, const QString& param)
{
	if (type == 2) {
		return TakePicture();
	} else if (type == 3) {
		return SendNotifyer(param.toInt());
	} else {
		SetErrorMassage("错误的路径动作类型");
		return false;
	}
}
